﻿using FantasyWereld.Code;
using FantasyWereld.Common;
using FantasyWereld.Data;
using FantasyWereld.Views;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Resources;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Notifications;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Settings Flyout item template is documented at http://go.microsoft.com/fwlink/?LinkId=273769

namespace FantasyWereld.UserControls
{
    public sealed partial class PreferencesSettingsFlyout : SettingsFlyout
    {
        public PreferencesSettingsFlyout()
        {
            this.InitializeComponent();

            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("NrOfItems"))
            {
                NrItems12.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["NrOfItems"]) == Constants.INITIAL_NR_ITEMS * 2;
                NrItems6.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["NrOfItems"]) == Constants.INITIAL_NR_ITEMS;
            }
            else
            {
                NrItems6.IsChecked = true;
            }

            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("UpdateFreqNews"))
            {
                PrefUpdateFrequency.Visibility = Visibility.Visible;
                try
                {
                    PrefFreq1.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]) == Constants.TASK_TIMEPERIOD / 6;
                    PrefFreq2.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]) == Constants.TASK_TIMEPERIOD / 2;
                    PrefFreq3.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]) == Constants.TASK_TIMEPERIOD;
                    PrefFreq4.IsChecked = Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]) == Constants.TASK_TIMEPERIOD * 2;
                }
                catch
                {
                }
            }
            else
            {
                PrefFreq3.IsChecked = true;
            }

            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("ShowNews"))
            {
                ShowNews.IsOn = Convert.ToBoolean(ApplicationData.Current.RoamingSettings.Values["ShowNews"]);
            }
            else
            {
                ShowNews.IsOn = true;
            }

            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("ShowPopupNews"))
            {
                ShowPopupNews.IsOn = Convert.ToBoolean(ApplicationData.Current.RoamingSettings.Values["ShowPopupNews"]);
            }
            else
            {
                ShowPopupNews.IsOn = true;
            }
        }

        private async void HandleCheck(object sender, RoutedEventArgs e)
        {
            RadioButton rb = sender as RadioButton;
            int nrItems = Constants.INITIAL_NR_ITEMS;
            switch (rb.Name)
            {
                case "NrItems12":
                    {
                        nrItems = Constants.INITIAL_NR_ITEMS * 2;
                        break;
                    }
                case "NrItems6":
                    {
                        nrItems = Constants.INITIAL_NR_ITEMS;
                        break;
                    }
            }

            if (Convert.ToInt16(ApplicationData.Current.RoamingSettings.Values["NrOfItems"]) != nrItems)
            {
                // Set roaming value to new value;
                ApplicationData.Current.RoamingSettings.Values["NrOfItems"] = nrItems;

                // Reload data in the app
                try
                {
                    // Clear memory and reload app with new value for TypeId
                    FWDataSource.Clear();

                    await FWDataSource.LoadDataAsync();

                    try
                    {
                        // Read books from disk and fetch images
                        FWDataSource.ReadReviewsFromDisk(false);
                    }
                    catch
                    {
                        // On error switch to offline mode
                        FWDataSource.ReadReviewsFromDisk(true);
                    }

                    // Add a Frame control to the window
                    var rootFrame = new Frame();
                    SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

                    if (!rootFrame.Navigate(typeof(MainPage)))
                        throw new Exception("Failed to create initial page");

                    // Place the frame in the current Window and ensure that it is active
                    Window.Current.Content = rootFrame;
                }
                catch
                {
                    showMessagebox();
                }
            }
        }

        private async void HandleCheck2(object sender, RoutedEventArgs e)
        {
            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("UpdateFreqNews"))
            {
                RadioButton rb = sender as RadioButton;
                int updateFreq = Constants.TASK_TIMEPERIOD;
                switch (rb.Name)
                {
                    case "PrefFreq1":
                        {
                            updateFreq = Constants.TASK_TIMEPERIOD / 6;
                            break;
                        }
                    case "PrefFreq2":
                        {
                            updateFreq = Constants.TASK_TIMEPERIOD / 2;
                            break;
                        }
                    case "PrefFreq3":
                        {
                            updateFreq = Constants.TASK_TIMEPERIOD;
                            break;
                        }
                    case "PrefFreq4":
                        {
                            updateFreq = Constants.TASK_TIMEPERIOD * 2;
                            break;
                        }
                }

                if (Convert.ToUInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]) != updateFreq)
                {
                    // Set roaming value to new value
                    ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"] = updateFreq;

                    // Reset background timer
                    try
                    {
                        var result = await BackgroundExecutionManager.RequestAccessAsync();
                        if (result == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity ||
                            result == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity)
                        {
                            foreach (var task in BackgroundTaskRegistration.AllTasks)
                            {
                                if (task.Value.Name == Constants.TASK_NAME)
                                    task.Value.Unregister(true);
                            }

                            BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
                            builder.Name = Constants.TASK_NAME;
                            builder.TaskEntryPoint = Constants.TASK_ENTRY;

                            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("UpdateFreqNews"))
                            {
                                var timerValue = Convert.ToUInt16(ApplicationData.Current.RoamingSettings.Values["UpdateFreqNews"]);
                                builder.SetTrigger(new TimeTrigger(timerValue, false));
                            }
                            else
                                builder.SetTrigger(new TimeTrigger(Constants.TASK_TIMEPERIOD, false));

                            var registration = builder.Register();
                        }
                    }
                    catch
                    {
                    }

                }
            }
        }

        private void HandleCheck3(object sender, RoutedEventArgs e)
        {
            ToggleSwitch rb = sender as ToggleSwitch;
            bool newValue = rb.IsOn;

            if (Convert.ToBoolean(ApplicationData.Current.RoamingSettings.Values["ShowNews"]) != rb.IsOn)
            {
                // Set roaming value to new value
                ApplicationData.Current.RoamingSettings.Values["ShowNews"] = rb.IsOn;

                // Reset Navigation object
                NavDataSource._NavDataSource.Initialize();

                // Add a Frame control to the window
                var rootFrame = new Frame();
                SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

                if (!rootFrame.Navigate(typeof(MainPage)))
                    throw new Exception("Failed to create initial page");

                // Place the frame in the current Window and ensure that it is active
                Window.Current.Content = rootFrame;
            }
        }

        private void HandleCheck4(object sender, RoutedEventArgs e)
        {
            ToggleSwitch rb = sender as ToggleSwitch;
            bool newValue = rb.IsOn;

            if (Convert.ToBoolean(ApplicationData.Current.RoamingSettings.Values["ShowPopupNews"]) != rb.IsOn)
            {
                // Set roaming value to new value
                ApplicationData.Current.RoamingSettings.Values["ShowPopupNews"] = rb.IsOn;
            }
        }

        private async void showMessagebox()
        {
            // Load resource handler
            var resourceLoader = new ResourceLoader();

            // Create the message dialog and set its content
            var messageDialog = new MessageDialog(resourceLoader.GetString("ErrorNoInternet"));

            // Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
            messageDialog.Commands.Add(new UICommand(resourceLoader.GetString("CloseButton"), new UICommandInvokedHandler(this.CommandInvokedHandler)));

            // Set the command that will be invoked by default
            messageDialog.DefaultCommandIndex = 0;

            // Set the command to be invoked when escape is pressed
            messageDialog.CancelCommandIndex = 1;

            // Show the message dialog
            await messageDialog.ShowAsync();
        }

        private void CommandInvokedHandler(IUICommand command)
        {
            App.Current.Exit();
        }
        
        private async void ClickUpdateBookDatabase(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Retrieve the Book Database from Fantasy Wereld webserver
            // When true is returned, there are more items than before, so store the results
            if (await FWDataSource.ProcessBooksAsync(Constants.BOOKFEED, Constants.BOOKFEED_BD_CODE))
            {
                // Reload data in the app
                try
                {
                    Utility.SendNotification(Constants.MESSAGE_NOTIFICATION_HEADER, Constants.MESSAGE_NOTIFICATION_NEW_BOOKS, Constants.NOTIFICATION_BOOKS);
                    await Utility.ReloadAppData();
                }
                catch
                {
                    showMessagebox();
                }
            }


            ProgressIndicator.Visibility = Visibility.Collapsed;
        }

        private async void ClickUpdateReviewDatabase(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Retrieve the total overview of Reviews from the Fantasy Wereld webserver
            // When true is returned, there are more items than before, so store the results
            if (await FWDataSource.ProcessReviewsAsync(Constants.REVIEWFEED, false))
            {
                // Reload data in the app
                try
                {
                    Utility.SendNotification(Constants.MESSAGE_NOTIFICATION_HEADER, Constants.MESSAGE_NOTIFICATION_NEW_REVIEWS, Constants.NOTIFICATION_REVIEWS);
                    await Utility.ReloadAppData();
                }
                catch
                {
                    showMessagebox();
                }
            }
            ProgressIndicator.Visibility = Visibility.Collapsed;
        }


        private async void ClickCleanupReviewDatabase(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Retrieve the total overview of Reviews from the Fantasy Wereld webserver
            // When true is returned, there are more items than before, so store the results
            await FWDataSource.CleanupReviewsAsync();

            ProgressIndicator.Visibility = Visibility.Collapsed;
        }

        private async void ClickUpdateKeywords(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Update all keywords
            await FWDataSource.UpdateKeywordsAsync();

            ProgressIndicator.Visibility = Visibility.Collapsed;
        }

        private async void ClickRepairReviewDatabase(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Retrieve the total overview of Reviews from the Fantasy Wereld webserver
            // When true is returned, there are more items than before, so store the results
            if (await FWDataSource.ProcessReviewsAsync(Constants.REVIEWFEED, true))
            {
                // Reload data in the app
                try
                {
                    Utility.SendNotification(Constants.MESSAGE_NOTIFICATION_HEADER, Constants.MESSAGE_NOTIFICATION_REPAIRED_REVIEWS, Constants.NOTIFICATION_REVIEWS);
                    await Utility.ReloadAppData();
                }
                catch
                {
                    showMessagebox();
                }
            }
            ProgressIndicator.Visibility = Visibility.Collapsed;
        }

        private async void ClickUpdateAuthorDatabase(object sender, RoutedEventArgs e)
        {
            ProgressIndicator.Visibility = Visibility.Visible;

            // Retrieve the total overview of Authors from the Fantasy Wereld webserver
            // When true is returned, there are more items than before, so store the results
            if (await FWDataSource.ProcessAuthorsAsync())
            {
                // Reload data in the app
                try
                {
                    Utility.SendNotification(Constants.MESSAGE_NOTIFICATION_HEADER, Constants.MESSAGE_NOTIFICATION_UPDATE_AUTHORS, Constants.NOTIFICATION_AUTHORS);
                    await Utility.ReloadAppData();
                }
                catch
                {
                    showMessagebox();
                }
            }
            ProgressIndicator.Visibility = Visibility.Collapsed;
        }

    }

}
